<template>
  <div class="system-menu-container">
		<div class="system-user-search mb15">
			<el-form :model="param" :inline="true" ref="queryFormRef" @keyup.enter.native="loadList">
				<el-form-item label="执行器" prop="jobGroup">
					<el-select v-model="param.jobGroup" placeholder="请选择执行器">
					<el-option :key="0" :value="0" label="全部"></el-option>
					<el-option v-for="(item) in jobGroups" :key="item.id" :value="item.id" :label="item.title"></el-option>
					</el-select>
				</el-form-item>
				<el-form-item label="调度状态"  prop="triggerStatus">
					<el-select v-model="param.triggerStatus" placeholder="启动状态">
					<el-option :key="-1" :value="-1" label="全部"></el-option>
					<el-option :key="0" :value="0" label="停止"></el-option>
					<el-option :key="1" :value="1" label="运行"></el-option>
					</el-select>
				</el-form-item>
				<el-form-item label="描述" prop="jobDesc">
					<el-input v-model="param.jobDesc" placeholder="任务描述" clearable></el-input>
				</el-form-item>
				<el-button type="primary" @click="loadList">
					<el-icon>
						<ele-Search />
					</el-icon>
					查询
				</el-button>
				<el-button type="primary" @click="reSetForm(queryFormRef)">
					<el-icon>
						<ele-Refresh />
					</el-icon>
					重置
				</el-button>
			</el-form>
		</div>
		<div class="home_common background_bg6">
			<div class="btnStyle">
				<el-button  type="primary" icon="ele-Plus" @click="addHandle()" >新增</el-button>
				<!-- <el-button  type="danger" icon="ele-Edit" @click="addOrUpdateHandle()" :disabled="dataListSelections.length !== 1">修改</el-button>
				<el-button  type="danger" icon="ele-Delete" @click="deleteHandle()" :disabled="dataListSelections.length <= 0 || hasDelFile">删除</el-button> -->
			</div>
		</div>
		<el-table :data="dataList" border v-loading="listLoading" @selection-change="selectionChangeHandle" style="width: 100%;">
			<el-table-column prop="jobGroup" label="执行器" :formatter="formatJobGroup"></el-table-column>
			<el-table-column prop="jobDesc" label="任务描述"></el-table-column>
			<el-table-column label="运行模式" width="200">
				<template #default="scope">
					{{scope.row.glueType}}:{{scope.row.executorHandler}}
				</template>
			</el-table-column>
			<el-table-column prop="executorParam" label="任务参数" width="150"></el-table-column>
			<el-table-column label="调度类型" width="180">
				<template #default="scope">
					{{scope.row.scheduleType}}:{{scope.row.scheduleConf}}
				</template>
			</el-table-column>
			<el-table-column prop="addTime" label="创建时间" width="150"></el-table-column>
			<el-table-column prop="triggerStatus" label="运行状态" :formatter="formatTriggerStatus" width="100"></el-table-column>
			<el-table-column label="操作">
				<template #default="scope">
					<el-button  type="primary" link @click="runHandle(scope.row)">执行一次</el-button>
					<el-button  type="primary" link @click="registryinfoHandle(scope.row)">注册节点</el-button>
					<el-button  type="primary" link @click="nextTimeHandle(scope.row)">下次执行时间</el-button>
					<el-button v-if="!scope.row.triggerStatus" type="primary" link @click="startHandle(scope.row)">启动</el-button>
					<el-button v-if="scope.row.triggerStatus" type="primary" link @click="stopHandle(scope.row)">停止</el-button>
					<el-button  type="primary" link @click="addOrUpdateHandle(scope.row)">修改</el-button>
					<el-button  type="primary" link @click="deleteHandle(scope.row.id)">删除</el-button>
				</template>
			</el-table-column>
		</el-table>
		<el-pagination
			@size-change="onHandleSizeChange"
			@current-change="onHandleCurrentChange"
			:pager-count="5"
			:page-sizes="[10, 50, 200]"
			v-model:current-page="param.page"
			background
			v-model:page-size="param.limit"
			layout="total, sizes, prev, pager, next, jumper"
			:total="total" small>
		</el-pagination>
		<el-dialog  ref="addOrUpdate" :title="!submitForm.id ? '新增' : '修改'"  v-model="dialogVisible" width="40%" class="customDialog">
			<el-form :model="submitForm" :rules="submitFormRule" ref="ruleFormRef" @keyup.enter.native="dataFormSubmit" label-width="120px">
				<el-row>
					<el-col :span="12">
						<el-form-item label="执行器" prop="jobGroup">
						<el-select v-model="submitForm.jobGroup" placeholder="请选择执行器" style="width:100%">
							<el-option v-for="(item) in jobGroups" :key="item.id" :value="item.id" :label="item.title"></el-option>
							</el-select>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="任务描述" prop="jobDesc">
						<el-input v-model="submitForm.jobDesc" placeholder="请输入任务描述" :maxlength="50"></el-input>
						</el-form-item>
					</el-col>
				</el-row>
				<el-row>
					<el-col :span="12">
						<el-form-item label="负责人" prop="author">
						<el-input v-model="submitForm.author" placeholder="请输入负责人" :maxlength="20"></el-input>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="报警邮件" prop="alarmEmail">
						<el-input v-model="submitForm.alarmEmail" placeholder="请输入报警邮件" :maxlength="100"></el-input>
						</el-form-item>
					</el-col>
				</el-row>
				<el-row>
					<el-col :span="12">
						<el-form-item label="调度类型" prop="scheduleType">
						<el-select v-model="submitForm.scheduleType" placeholder="调度类型" style="width:100%">
							<el-option v-for="(value,key) in ScheduleTypeEnum" :key="key" :value="key" :label="value"></el-option>
						</el-select>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item :label="cronLable" prop="scheduleConf">
						<el-input v-if="submitForm.scheduleType === 'CRON' || submitForm.scheduleType === 'FIX_RATE'" v-model="submitForm.scheduleConf" :placeholder="placeholderCon" :maxlength="128">
						</el-input>
						<!-- <el-popover v-if="submitForm.scheduleType === 'CRON'" v-model="cronPopover" ref="cronPopoverS" placement="right-end" trigger="click">
							<Cron v-model="submitForm.scheduleConf" @change="changeCron" @close="cronPopover=false" i18n="cn"></Cron>
						</el-popover>
						<el-input v-if="submitForm.scheduleType === 'CRON' || submitForm.scheduleType === 'FIX_RATE'" v-model="submitForm.scheduleConf" :placeholder="placeholderCon" :maxlength="128">
							<template #append>
								<el-button v-if="submitForm.scheduleType === 'CRON'" v-popover:cronPopoverS icon="el-icon-edit" ></el-button>
							</template>
						</el-input> -->
						</el-form-item>
					</el-col>
				</el-row>
				<el-row>
					<el-col :span="12">
						<el-form-item label="运行模式" prop="glueType">
						<el-select v-model="submitForm.glueType" placeholder="请选择运行模式" style="width:100%" @change="glueTypeChage">
							<el-option v-for="(value,key) in GlueTypeEnum" :key="key" :value="key" :label="value"></el-option>
							</el-select>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="JobHandler" prop="executorHandler">
						<el-input v-model="submitForm.executorHandler" placeholder="请输入JobHandler" :maxlength="100"></el-input>
						</el-form-item>
					</el-col>
				</el-row>
				<el-row>
					<el-col :span="12">
						<el-form-item label="路由策略" prop="executorRouteStrategy">
						<el-select v-model="submitForm.executorRouteStrategy" placeholder="请选择路由策略" style="width:100%">
							<el-option v-for="(value,key) in ExecutorRouteStrategyEnum" :key="key" :value="key" :label="value"></el-option>
							</el-select>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="子任务ID" prop="childJobId">
						<el-input v-model="submitForm.childJobId" placeholder="请输入子任务ID，多个逗号分隔" :maxlength="100"></el-input>
						</el-form-item>
					</el-col>
				</el-row>
				<el-row>
					<el-col :span="12">
						<el-form-item label="阻塞策略" prop="executorBlockStrategy">
						<el-select v-model="submitForm.executorBlockStrategy" placeholder="请选择阻塞策略" style="width:100%">
							<el-option v-for="(value,key) in ExecutorBlockStrategyEnum" :key="key" :value="key" :label="value"></el-option>
						</el-select>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="调度过期策略" prop="misfireStrategy">
						<el-select v-model="submitForm.misfireStrategy" placeholder="请选过期策略" style="width:100%">
							<el-option v-for="(value,key) in MisfireStrategyEnum" :key="key" :value="key" :label="value"></el-option>
						</el-select>
						</el-form-item>
					</el-col>
				</el-row>
				<el-row>
					<el-col :span="12">
						<el-form-item label="超时时间" prop="executorTimeout">
						<el-input v-model="submitForm.executorTimeout" placeholder="请输入超时时间，单位秒，大于0时生效" type="number" :maxlength="6"></el-input>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="失败重试次数" prop="executorFailRetryCount">
						<el-input v-model="submitForm.executorFailRetryCount" placeholder="请输入失败重试次数，大于0时生效"  type="number" :maxlength="4"></el-input>
						</el-form-item>
					</el-col>
				</el-row>
				<el-row>
					<el-col :span="24">
						<el-form-item label="参数" prop="executorParam">
						<el-input v-model="submitForm.executorParam" placeholder="请输入参数" :maxlength="512"></el-input>
						</el-form-item>
					</el-col>
				</el-row>
			</el-form>
			<template #footer>
				<span class="dialog-footer">
					<el-button @click="handleClose">取消</el-button>
					<el-button type="primary" @click="dataFormSubmit">确定</el-button>
				</span>
			</template>
		</el-dialog>
	</div>
</template>

<script lang="ts">
import { ref, toRefs, reactive, watch, onMounted, defineComponent } from 'vue'
import type { FormInstance } from 'element-plus'
import { ElMessage, ElMessageBox, ElLoading } from 'element-plus'
// import {cron} from 'vue-cron'
//局部引入
import {scheduleApi} from '/@/api/scheduleapi'
export default defineComponent({
	components:{},
	setup () {
		const queryFormRef = ref<FormInstance>()
		const ruleFormRef = ref();
		const state = reactive({
			isShow: false,
			listLoading: false,
			dataList: [],
			total: 0,
			totalSelect: 0,
			jobGroups: [],
			jobGroupMap: {},
			param: {
				page: 1,
				limit: 10,
				jobGroup: 0,
				triggerStatus: -1,
				jobDesc: ''
			},
			submitForm: {
				id: 0,
				jobGroup: '',
				jobDesc: '',
				author: '',
				alarmEmail: '',
				executorRouteStrategy: '',
				executorHandler: '',
				executorParam: '',
				executorBlockStrategy: '',
				executorTimeout: '',
				executorFailRetryCount: '',
				glueType: '',
				childJobId: '',
				scheduleType: '',
				scheduleConf: '',
				misfireStrategy: ''
			},
			dataListSelections: [],
			dialogVisible: false,
			cronLable: '',
			placeholderCon: '',
			cronPopover: false,
			ExecutorRouteStrategyEnum: {
				'FIRST': '第一个',
				'LAST': '最后一个',
				'ROUND': '轮询',
				'RANDOM': '随机',
				'CONSISTENT_HASH': '一致性HASH',
				'LEAST_FREQUENTLY_USED': '最不经常使用',
				'LEAST_RECENTLY_USED': '最近最久未使用',
				'FAILOVER': '故障转移',
				'BUSYOVER': '忙碌转移',
				'SHARDING_BROADCAST': '分片广播'
			},
			GlueTypeEnum: {
				'BEAN': 'BEAN',
				'GLUE_GROOVY': 'GLUE(Java)',
				'GLUE_SHELL': 'GLUE(Shell)',
				'GLUE_PYTHON': 'GLUE(Python)',
				'GLUE_PHP': 'GLUE(PHP)',
				'GLUE_NODEJS': 'GLUE(Nodejs)',
				'GLUE_POWERSHELL': 'GLUE(PowerShell)'
			},
			ExecutorBlockStrategyEnum: {
				'SERIAL_EXECUTION': '单机串行',
				'DISCARD_LATER': '丢弃后续调度',
				'COVER_EARLY': '覆盖之前调度'
			},
			MisfireStrategyEnum: {
				'DO_NOTHING': '忽略',
				'FIRE_ONCE_NOW': '立即执行一次'
			},
			ScheduleTypeEnum: {
				'NONE': '无',
				'CRON': 'CRON表达式',
				'FIX_RATE': '固定速度'
			},
			submitFormRule: {
				jobGroup: [
					{ required: true, message: '执行器不能为空', trigger: 'blur' }
				],
				jobDesc: [
					{ required: true, message: '任务描述不能为空', trigger: 'blur' }
				],
				executorRouteStrategy: [
					{ required: true, message: '路由策略不能为空', trigger: 'blur' }
				],
				scheduleType: [
					{ required: true, message: '调度类型不能为空', trigger: 'blur' }
				],
				scheduleConf: [
					{ required: false, message: 'Cron表达式不能为空', trigger: 'blur' }
				],
				glueType: [
					{ required: true, message: '运行模式不能为空', trigger: 'blur' }
				],
				executorHandler: [
					{ required: false, message: 'JobHandler不能为空', trigger: 'blur' }
				],
				executorBlockStrategy: [
					{ required: true, message: '阻塞策略不能为空', trigger: 'blur' }
				],
				misfireStrategy: [
					{ required: true, message: '过期策略不能为空', trigger: 'blur' }
				],
				author: [
					{ required: true, message: '负责人不能为空', trigger: 'blur' }
				]
			}
		})

		// 页面加载时
		onMounted(() => {
			initJobGrous()
			// 列表查询
			loadList()
		})

		const initJobGrous = () => {
			scheduleApi().getXxlJobGroupList().then(data => {
			if (data && data.code === 0) {
				state.jobGroups = data.list
				data.list.forEach(item => {
					state.jobGroupMap[item.id] = item.title
				})

			} else {
				this.jobGroups = []
			}
			}).catch(()=>{
				state.jobGroups = []
			}).finally(()=>{
			})
		}
		//查询
		const loadList = () => {
			state.listLoading = true
			scheduleApi().getXxlJobJobList(state.param).then(data => {
				if (data && data.code === 0) {
					state.dataList = data.page.list
					state.total = data.page.totalCount
				} else {
					state.dataList = []
					state.total = 0
				}
			}).catch(() => {
			}).finally(() => {
				state.listLoading = false
			})
		}

		//重置
		const reSetForm = (formEl: FormInstance | undefined) => {
			if (!formEl) return
			formEl.resetFields()
			state.param.page = 1
			loadList()
		}
		// 分页改变
		const onHandleSizeChange = (val: number) => {
			state.param.limit = val;
			loadList()
		}
		// 分页改变
		const onHandleCurrentChange = (val: number) => {
			state.param.page = val;
			loadList()
		}
		const selectionChangeHandle = (val: any) => {
			state.dataListSelections = val
		}

		const formatJobGroup = (row, column, cellValue, index) => {
			return state.jobGroupMap[cellValue]
		}

		const formatTriggerStatus = (row, column, cellValue, index) => {
			return cellValue ? '运行' : '停止';
		}
		const addHandle = () => {
			state.submitForm = {
				id: 0,
				jobGroup: '',
				jobDesc: '',
				author: '',
				alarmEmail: '',
				executorRouteStrategy: '',
				executorHandler: '',
				executorParam: '',
				executorBlockStrategy: '',
				executorTimeout: '',
				executorFailRetryCount: '',
				glueType: '',
				childJobId: '',
				scheduleType: '',
				scheduleConf: '',
				misfireStrategy: ''
			}
			state.dialogVisible = true
		}

		const addOrUpdateHandle = (row: any | undefined) => {
			if(!row){
				state.submitForm = state.dataListSelections[0]
			} else {
				state.submitForm = row
			}
			state.dialogVisible = true
		}
		watch(() => state.submitForm.scheduleType, (val:string) => {
			if(val === 'FIX_RATE') {
				state.cronLable = '固定速度'
				state.placeholderCon = '请输入固定速度秒数'
				state.submitFormRule.scheduleConf[0].required = true;
				state.submitFormRule.scheduleConf[0].message = '固定速度秒数不能为空';
			} else if(val === 'CRON') {
				state.cronLable = 'CRON表达式'
				state.placeholderCon = '请输入Cron表达式'
				state.submitFormRule.scheduleConf[0].required = true;
				state.submitFormRule.scheduleConf[0].message = 'Cron表达式不能为空';
			} else {
				state.cronLable = ''
				state.placeholderCon = ''
				state.submitFormRule.scheduleConf[0].required = false;
				state.submitFormRule.scheduleConf[0].message = '';
			}
		})
		// 删除
		const deleteHandle = (id: string | undefined) => {
			ElMessageBox.confirm('是否确定删除', '提示', {
				confirmButtonText: '确定',
				cancelButtonText: '取消',
			}).then(() => {
				var ids = id ? [id] : state.dataListSelections.map(item => {
					return item.id
				})
				const loading = ElLoading.service({
					lock: true,
					text: '处理中',
					background: 'rgba(0, 0, 0, 0.7)',
				})
				scheduleApi().deleteXxlJobInfo(ids).then((data) => {
					if (data && data.code === 0) {
						ElMessage.success('删除成功！')
						loadList()
					} else {
						ElMessage.error(data.msg)
					}
				}).catch(() => {
					ElMessage.error('删除失败！')
				}).finally(() => {
					loading.close()
				})
			})
		}

      const changeCron = (val: any) => {
        state.submitForm.scheduleConf = val
      }
		//取消修改
		const handleClose = () => {
			state.dialogVisible = false
			ruleFormRef.value!.clearFiles()
			loadList()
		}
		const dataFormSubmit = () => {
			ruleFormRef.value.validate((valid: boolean) => {
				if (valid) {
					const loading = ElLoading.service({
						lock: true,
						text: '处理中',
						background: 'rgba(0, 0, 0, 0.7)',
					})
					if(!state.submitForm.id) {
						//新增
						scheduleApi().saveXxlJobInfo(state.submitForm).then(data => {
							loading.close()
							if (data && data.code === 0) {
								state.dialogVisible = false
								loadList()
								ElMessage.success('保存成功')
							} else {
								ElMessage.error(data.msg)
							}
						}).catch(() => {
							loading.close()
							ElMessage.error("保存失败！")
						})
					} else {
						//修改
						scheduleApi().saveXxlJobInfo(state.submitForm).then(data => {
							loading.close()
							if (data && data.code === 0) {
								state.dialogVisible = false
								loadList()
								ElMessage.success('保存成功')
							} else {
								ElMessage.error(data.msg)
							}
						}).catch(() => {
							loading.close()
							ElMessage.error("保存失败！")
						})
					}
				} else {
					return false;
				}
			})
		}
		//执行一次
		const runHandle = (row: any) => {
			ElMessageBox.prompt('请输入执行参数', '提示', {
				confirmButtonText: '确定',
				cancelButtonText: '取消',
			}).then(({ value }) => {
				const loading = ElLoading.service({
					lock: true,
					text: '处理中',
					background: 'rgba(0, 0, 0, 0.7)',
				})
				scheduleApi().runJobInfo(row.id, value).then((data) => {
					if (data && data.code === 0) {
						ElMessage.success('执行成功！')
						loadList()
					} else {
						ElMessage.error(data.msg)
					}
				}).catch(() => {
					ElMessage.error('执行失败！')
				}).finally(() => {
					loading.close()
				})
			})
		}
		//查看注册节点
		const registryinfoHandle = (row: any) => {
			scheduleApi().getRegistryinJobInfo(row.jobGroup).then(data => {
				if (data && data.code === 0) {
					ElMessageBox.alert(data.msg, '注册节点', {
					confirmButtonText: '确定',
					dangerouslyUseHTMLString: true
					})
				} else {
					ElMessage.error(data.msg)
				}
			}).catch(()=>{
				ElMessage.error('获取注册节点信息失败')
			})
		}
		//查看下次执行时间
		const nextTimeHandle = (row: any) => {
			scheduleApi().getNextTimeJobInfo(row.scheduleType, row.scheduleConf).then(data => {
				if (data && data.code === 0) {
					// let html = ''
					// html = data.timeList.forEach(item => {
					//   html + item + '<p>'
					// })
					ElMessageBox.alert(data.msg, '下次执行时间', {
					confirmButtonText: '确定',
					dangerouslyUseHTMLString: true
					})
				} else {
					ElMessage.error(data.msg)
				}
			}).catch(()=>{
				ElMessage.error('获取下次执行时间信息失败')
			})
		}
		//启动定时任务
		const startHandle = (row: any) => {
			scheduleApi().startJobInfo(row.id).then(data => {
				if (data && data.code === 0) {
					ElMessage.success('启动成功')
				} else {
					ElMessage.error(data.msg)
				}
				loadList();
			}).catch((err)=>{
				ElMessage.error('启动失败')
			})
		}
		//停止定时任务
		const stopHandle = (row: any) => {
			scheduleApi().stopJobInfo(row.id).then(data => {
				if (data && data.code === 0) {
					ElMessage.success('停止成功')
				} else {
					ElMessage.error(data.msg)
				}
				loadList();
			}).catch(()=>{
				ElMessage.error('停止失败')
			})
		}
		return {
			loadList,
			reSetForm,
			queryFormRef,
			deleteHandle,
			dataFormSubmit,
			handleClose,
			selectionChangeHandle,
			ruleFormRef,
			formatJobGroup,
			formatTriggerStatus,
			addHandle,
			addOrUpdateHandle,
			initJobGrous,
			onHandleSizeChange,
			onHandleCurrentChange,
			changeCron,
			runHandle,
			registryinfoHandle,
			nextTimeHandle,
			startHandle,
			stopHandle,
			...toRefs(state),
		}
	}
})
</script>

<style>

</style>